package icdecs.mail;

import icdecs.system.SystemProperties;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class SimpleEmail {
	private static final String ZIP_FILE_PREFIX = "icdecs_";
	private static final String ZIP_FILE_SUFFIX = ".zip";

	private static final String PREFIX_GETLIST_LOG = "getList.log";
	private static final String PREFIX_REGISTLIST_LOG = "registList.log";

	List<String> fileList;

	String pathAttachmentFolder;
	String pathLogFolder;
	String nameZipFile;
	String pathToZipFile;

	/**
	 * this is function initial data
	 */
	public void init(String date) {
		pathAttachmentFolder = SystemProperties.getZipDir();
		pathLogFolder = SystemProperties.getZipTargetDir();
		nameZipFile = ZIP_FILE_PREFIX + date + ZIP_FILE_SUFFIX;
		pathToZipFile = pathAttachmentFolder + "/" + nameZipFile;

		String pass = "123456789";
		Properties props = System.getProperties();
		props.put("mail.smtp.starttls.enable",
				SystemProperties.getMailStartTLSEnable()); // added this line
		props.put("mail.smtp.host", SystemProperties.getMailSmtpHost());
		props.put("mail.smtp.user", SystemProperties.getMailAddressFrom());
		props.put("mail.smtp.password", pass);
		props.put("mail.smtp.port", SystemProperties.getMailPort());
		props.put("mail.smtp.auth", SystemProperties.getMailSmtpAuth());

	}

	/**
	 * This is send mail function. Using to send mail with attach log files
	 * 
	 * @throws MessagingException
	 */

	public void sendMail(String dateOfFile) throws Exception {
		init(dateOfFile);
		String pass = "123456789";
		Properties props = System.getProperties();
		String[] to = { SystemProperties.getMailAddressTo() }; // added this
																// line
		Session session = Session.getDefaultInstance(props, null);
		MimeMessage message = new MimeMessage(session);
		message.setFrom(new InternetAddress(SystemProperties
				.getMailAddressFrom()));

		InternetAddress[] toAddress = new InternetAddress[to.length];

		// To get the array of addresses
		for (int i = 0; i < to.length; i++) { // changed from a while loop
			toAddress[i] = new InternetAddress(to[i]);
		}
		System.out.println(Message.RecipientType.TO);

		for (int i = 0; i < toAddress.length; i++) { // changed from a while
														// loop
			message.addRecipient(Message.RecipientType.TO, toAddress[i]);
		}
		message.setSubject("sending in a group");
		message.setText("Welcome to JavaMail");

		// Create the message part
		BodyPart messageBodyPart = new MimeBodyPart();

		// Fill the message
		messageBodyPart.setText("This is message body");

		// Create a multipar message
		Multipart multipart = new MimeMultipart();

		// Set text message part
		multipart.addBodyPart(messageBodyPart);

		// Part two is attachment
		messageBodyPart = new MimeBodyPart();
		fileList = new ArrayList<String>();
		generateFileList(new File(SystemProperties.getZipTargetDir()),
				dateOfFile);
		if (fileList.size() == 0) {
			throw new Exception("Not file found!");
		}
		zipIt(pathToZipFile);
		DataSource source = new FileDataSource(pathToZipFile);
		messageBodyPart.setDataHandler(new DataHandler(source));
		messageBodyPart.setFileName(nameZipFile);
		multipart.addBodyPart(messageBodyPart);

		// Send the complete message parts
		message.setContent(multipart);

		Transport transport = session.getTransport("smtp");
		transport.connect(SystemProperties.getMailSmtpHost(),
				SystemProperties.getMailAddressFrom(), pass);
		transport.sendMessage(message, message.getAllRecipients());
		transport.close();
	}

	/**
	 * function compress
	 * 
	 * @param zipFile
	 *            output ZIP file location
	 */
	public void zipIt(String zipFile) {

		byte[] buffer = new byte[1024];

		try {

			FileOutputStream fos = new FileOutputStream(zipFile);
			ZipOutputStream zos = new ZipOutputStream(fos);

			for (String file : this.fileList) {

				System.out.println("File Added : " + file);
				ZipEntry ze = new ZipEntry(file);
				zos.putNextEntry(ze);

				FileInputStream in = new FileInputStream(this.pathLogFolder
						+ File.separator + file);

				int len;
				while ((len = in.read(buffer)) > 0) {
					zos.write(buffer, 0, len);
				}

				in.close();
			}

			zos.closeEntry();
			// remember close it
			zos.close();

			System.out.println("Done");
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Traverse a directory and get all files, and add the file into fileList
	 * 
	 * @param node
	 *            file or directory
	 */
	public void generateFileList(File node, String date) {

		// add file only
		if (node.isFile()) {
			if (node.getName().startsWith(PREFIX_GETLIST_LOG)
					|| node.getName().startsWith(PREFIX_REGISTLIST_LOG)) {
				Date dateFile = new Date(node.lastModified());
				if (date.equals(new SimpleDateFormat("yyyy-MM-dd")
						.format(dateFile))) {
					fileList.add(generateZipEntry(node.getAbsoluteFile()
							.toString()));
				}
			}
		}

		if (node.isDirectory()) {
			String[] subNote = node.list();
			for (String filename : subNote) {
				generateFileList(new File(node, filename), date);
			}
		}

	}

	/**
	 * Format the file path for zip
	 * 
	 * @param file
	 *            file path
	 * @return Formatted file path
	 */
	private String generateZipEntry(String file) {
		return file.substring(this.pathLogFolder.length() + 1, file.length());
	}

}
